/**
* All Rights Reserved , Copyright (C) 2021 , 青岛鼎信通讯股份有限公司
*
* SdProjectReviewService
* SD项目复盘结项
*
* 修改纪录
* 2021-12-10 版本：1.0 jiangtao 创建。
* @version 版本：1.0
* @author 作者：jiangtao
* 创建日期：2021-12-10
*/
package com.topscomm.gpm.service.impl;

import com.topscomm.basic.exception.MessageException;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.mms.pojo.MmsDeptExtraInfoEntity;
import com.topscomm.mms.service.impl.MmsDeptExtraInfoService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.gpm.GpmSystemConst;
import com.topscomm.gpm.pojo.GpmProjectEntity;
import com.topscomm.gpm.pojo.GpmProjectOverdueInfoEntity;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.FlowDatacodeCache;
import com.topscomm.tap.common.SessionUserBean;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.gpm.service.IGpmProjectReviewService;
import com.topscomm.gpm.service.impl.auto.GpmProjectReviewServiceAuto;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.cbo.service.impl.CboSysParamService;
import com.topscomm.gpm.pojo.GpmProjectReviewEntity;

import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Service(value = "gpmProjectReviewService")
@Scope(value = "singleton")
public class GpmProjectReviewService extends GpmProjectReviewServiceAuto implements IGpmProjectReviewService {

	@Autowired
	private GpmProjectService gpmProjectService;
	@Autowired
	private DatacodeCache datacodeCache;
	FlowDatacodeCache flowDatacodeCache = new FlowDatacodeCache();
	protected List<Map<String, Object>> flowidList = new ArrayList();
	@Autowired
	private GpmProjectTaskService gpmProjectTaskService;
	@Autowired
	private GpmProjectMilepostService gpmProjectMilepostService;
	@Autowired
	private MmsDeptExtraInfoService mmsDeptExtraInfoService;
	@Autowired
	private GpmProjectOverdueInfoService gpmProjectOverdueInfoService;

	/**
	 * @author: jiangtao
	 * @date: 2021-12-10
	 * @param entity
	 * @throws ServiceException
	 * @description:单号生成
	 * @modify:
	 */
	@Override
	protected void beforeInsert(BasicEntity entity){
		super.beforeInsert(entity);
		if (entity.getId() <= 0) {// 赋值Id和单号
			long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
			entity.setId(arrayId[0]);
			String docNo = String.valueOf(arrayId[0]);
			docNo = docNo.substring(0, 6) + docNo.substring(9);
			entity.setValue(GpmProjectReviewEntity.FieldDocno, docNo);
		}
		GpmProjectReviewEntity projectReviewEntity = (GpmProjectReviewEntity) entity;
		entity.setValue(GpmProjectReviewEntity.FieldReviewcode,this.generateReviewCode(projectReviewEntity.getProjectcode(),projectReviewEntity.getDocno()));
	}

	private String generateReviewCode (String projectcode,String docNo){
		//赋值复盘编号
		String reviewcode= "FP";
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("projectcode='{0}'",projectcode);
		GpmProjectEntity projectEntity = gpmProjectService
				.queryObjectByWhere(sql.toString());
		String projectlevel = projectEntity.getProjectlevel();
		projectlevel= datacodeCache.getValueDynamic("GpmProjectLevel", projectlevel, "code", "name");
		SimpleDateFormat sdFormat = new SimpleDateFormat("yyMMdd");
		String datacode = sdFormat.format(new Date());
		String substring = datacode.substring(0, 4);
		String flowCode = docNo.substring(docNo.length() - 3);
		reviewcode=reviewcode+projectlevel+substring+flowCode;
		return reviewcode;
	}


	/***
	 * @description: 新增和保存方法
	 * @param inputMap
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/13 15:05
	 * @modify:
	 */
	@Override public Map<String, Object> doSave(Map<String, Object> inputMap) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		// 基础信息表
		Map<String, Object> basicInfo = (Map<String, Object>) inputMap.get("basicInfo");
		// 来源信息表
		List<Map<String, Object>> productSourceInfo = (List<Map<String, Object>>) inputMap.get("productSourceInfo");
		long id = 0L;
		if(basicInfo == null) {
			return resultMap;
		}
		GpmProjectReviewEntity reviewEntity = new GpmProjectReviewEntity();
		reviewEntity.convertFromMap(basicInfo);
		reviewEntity = this.saveProjectInfo(reviewEntity);
		resultMap.put("id", reviewEntity.getId());
		return resultMap;
	}


	/***
	 * @description: 保存复盘主表信息
	 * @param reviewEntity
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/13 15:09
	 * @modify:
	 */
	private GpmProjectReviewEntity saveProjectInfo(GpmProjectReviewEntity reviewEntity) {
		long id = reviewEntity.getId();
		if (id <= 0) {
			long[] arrayId = PrimaryKeyUtil.GeneIDs(reviewEntity.getTableName(), 1);
			id = arrayId[0];
			reviewEntity.setId(id);
			reviewEntity.setState(0);
			String docNo = String.valueOf(id);
			docNo = "SDRe" + docNo.substring(0, 6) + docNo.substring(9);
			reviewEntity.setDocno(docNo);
			this.insert(reviewEntity);
		} else {
			this.updateEntity(reviewEntity);
		}
		return reviewEntity;
	}

	/***
	 * @description: 判断flowid和是否存在审批中的流程
	 * @param entity
	 * @param sessionUserBean
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/23 13:42
	 * @modify:
	 */
	@Override
	protected void beforeSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
		super.beforeSubmit(entity, sessionUserBean);
		GpmProjectReviewEntity projectReviewEntity = (GpmProjectReviewEntity) entity;
		this.flowidList= flowDatacodeCache
				.getApprovalFlowListMap("ApprovalFlow_GpmProjectReview",
						projectReviewEntity.getApplyusercode(), "sortcode");
		if(flowidList.size()>0){
			projectReviewEntity.setFlowid(ConvertUtil.convertToLong(flowidList.get(0).get("id")));
		}else{
			throw new ServiceException("没有匹配的审批流，请联系管理员！");
		}
		String projectcode = projectReviewEntity.getProjectcode();
		// 判断是否可以结项
		boolean whetherend = this.judegEndTpye(projectcode);
		if(!whetherend) {
			throw new ServiceException("存在未完成的任务或者里程碑，不允许进行复盘结项！");
		}
		// 判断是否有重复的已经提交的复盘
		long id = projectReviewEntity.getId();
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" projectcode = '{0}' and id != {1} and state in ('1', '9')",projectcode,id);
		int count = this.getCount(sql.toString());
		if(count>0) {
			throw new ServiceException("该项目存在审批中的复盘，不允许再次提交审批！");
		}
	}

	/***
	 * @description: 判断是否存在未结项的任务或者里程碑
	 * @param projectcode
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/23 15:37
	 * @modify:
	 */
	@Override
	public Boolean judegEndTpye(String projectcode) {
		StringBufferProxy whereSql = new StringBufferProxy();
		whereSql.appendSingle(" taskstate in ({1}, {2}) and projectcode = '{0}' ",
				projectcode,
				GpmSystemConst.TaskStateCode.TaskNotStartCode,
				GpmSystemConst.TaskStateCode.TaskIncompleteCode);
		// 未完成的任务数
		int unfinishedTaskCount = this.gpmProjectTaskService.getCount(whereSql.toString());
		whereSql.clear();
		// 未达成的里程碑数
		whereSql.appendSingle(" projectcode = '{0}' and milepoststate = '{1}' and enabled = 1 " ,
				projectcode, GpmSystemConst.MilepostStateCode.MilepostIncompleteCode);
		int unfinishedMilePostCount = this.gpmProjectMilepostService.getCount(whereSql.toString());
		whereSql.clear();
		// 已达成的里程碑数
		whereSql.appendSingle(" projectcode = '{0}' and milepoststate = '{1}' and enabled = 1 ",
				projectcode, GpmSystemConst.MilepostStateCode.MilepostCompleteCode);
		int finishedMilePostCount = this.gpmProjectMilepostService.getCount(whereSql.toString());
		return unfinishedTaskCount == 0 && unfinishedMilePostCount == 0 && finishedMilePostCount > 0;
	}

	/**
	 * @author: zhangjunyao
	 * @date: 2021-12-23
	 * @description: 修改项目是否公开的权限
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String changePermission(String projectId) {
		GpmProjectEntity projectEntity = gpmProjectService.queryById(projectId);
		String message = "";
		if (projectEntity != null) {
			if (projectEntity.getOpen() == 1) {
				projectEntity.setOpen(0);
				message = "取消公开成功！";
			} else {
				projectEntity.setOpen(1);
				message = "公开成功！";
			}
			gpmProjectService.updateEntity(projectEntity);
		} else {
			throw new ServiceException("找不到该项目记录！");
		}
		return message;
	}

	/**
	 *
	 * @param sql
	 * @author zhangjunyao
	 * @date 2022-01-19
	 * @description 判断是否为省总或CFO
	 * @return boolean
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean isProvinceManagerOrCfo(StringBufferProxy sql) {
		boolean isProvinceManagerOrCfo = false;
		StringBufferProxy whereSql = new StringBufferProxy();
		whereSql.appendSingle(" {0} = '{1}' or {2} = '{1}'", MmsDeptExtraInfoEntity.FieldProvincemanagercode,
				this.getSessionUserBean().getUser().getCode(), MmsDeptExtraInfoEntity.FieldCfocode);
		List<MmsDeptExtraInfoEntity> mmsDeptExtraInfoEntities = mmsDeptExtraInfoService.queryByWhere(whereSql.toString());
		if (CollectionUtils.isEmpty(mmsDeptExtraInfoEntities)) {
			return isProvinceManagerOrCfo;
		}
		isProvinceManagerOrCfo = true;
		String deptCommonCode = mmsDeptExtraInfoEntities.get(0).getDeptcommoncode();
		sql.appendSingle(" and {0}.{1} = '{2}'", GpmProjectReviewEntity.tableName, GpmProjectReviewEntity.FieldDeptcommoncode1, deptCommonCode);
		return isProvinceManagerOrCfo;
	}

	/**
	 *
	 * @param projectId
	 * @author zhangjunyao
	 * @date 2022-01-19
	 * @description 判断是否已经提交复盘
	 * @return boolean
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean ifReviewed(String projectId) {
		boolean ifReviewed = false;
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" projectid = '{0}' and state in (1,9) ", projectId);
		List<GpmProjectReviewEntity> gpmProjectReviewEntity = this.queryByWhere(sql.toString());
		if (!CollectionUtils.isEmpty(gpmProjectReviewEntity)) {
			ifReviewed = true;
		}
		return ifReviewed;
	}

	/**
	 *
	 * @param paraMap
	 * @author hdy
	 * @date 2022-03-24
	 * @description 项目概述增加系统自定义内容:
	 * 本项目于xx年xx月xx日中标/签订合同/提交借用申请，
	 * 中标/签订合同/借用金额为xx万元（涉及xx产品xx只），
	 * 于xx年xx月xx日完成项目立项。
	 * 项目目标为：xxxxx。
	 * 项目执行过程中存在项目超期、n个里程碑超期、n个流程超期、n个任务超期 ，
	 * 最终项目于xx年xx月xx日完成交付xx万元（xx产品xx只），实际履约至m%。
	 * @return string
	 */
	@Override
	public String addsummary(Map<String, Object> paraMap) {
		if (!paraMap.containsKey("projectid")) {
			throw new MessageException("请选择正确的通用项目！");
		}
		String projectId = ConvertUtil.convertToString(paraMap.get("projectid"));
		GpmProjectEntity gpmProjectEntity = gpmProjectService.queryById(projectId);
		StringBufferProxy content = new StringBufferProxy();
		StringBufferProxy sql = new StringBufferProxy();
		//1、本项目于xx年xx月xx日[1]中标/签订合同/提交借用申请
		String sourcetype = ConvertUtil.convertToString(gpmProjectEntity.getSourcetype());
		sql.appendSingle("sourcetype = '{0}' and projectid = '{1}'", sourcetype,projectId);
		String dispsourcetype = "";
		SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy年MM月dd日");
		String applydate = "";
		content.appendSingle("本项目于{0}{1}，", applydate,dispsourcetype);
		//3、（涉及xx产品xx只[3]）
		content.appendSingle("（涉及");
		sql.clear();
		sql.appendSingle("PROJECTID = '{0}'", projectId);
//		List<GpmProductInfoEntity> sdProductInfoEntities = sdProductInfoService.queryByWhere(sql.toString());
		String productname = "";
		String amount = "";
//		int index = sdProductInfoEntities.size();
//		for(GpmProductInfoEntity gpmProductInfoEntity : sdProductInfoEntities) {
//			index--;
//			productname = gpmProductInfoEntity.getProductname();
//			content.appendSingle("{0}产品",productname	);
//			amount = ConvertUtil.convertToString(gpmProductInfoEntity.getAmount());
//			if(!"".equals(amount)) {
//				content.appendSingle("{0}只",amount);
//			}
//			if(index!=0) {
//				content.appendSingle("，",amount);
//			}
//		}
		content.appendSingle("），");
		//4、于xx年xx月xx日[4]完成项目立项。
		sql.clear();
		sql.appendSingle("SELECT ENDDATE FROM CBOAPPROVALFLOWINS c,SDWFFORM s  where c.SOURCETYPE = 'GpmWfForm' AND c.SOURCEID  = s.ID AND s.SOURCETYPE = 'GpmProject' AND s.FINALSOURCEID = '{0}'",
				projectId);
		List<Map<String, Object>> maps = this.selectExecute(sql.toString());
		if(maps.size()>0) {
			String enddate = sdFormat.format(ConvertUtil.convertToDate(maps.get(0).get("enddate")));
			content.appendSingle("于{0}完成项目立项。",enddate);
		}
		//5、项目目标为：xxxxx
		content.appendSingle("项目目标为：{0}。", gpmProjectEntity.getTarget());
		//6、项目执行过程中存在项目超期、n个里程碑超期、n个流程超期、n个任务超期
		sql.clear();
		sql.appendSingle("projectid = '{0}'", projectId);
		List<GpmProjectOverdueInfoEntity> sdProjectOverdueInfoEntities = gpmProjectOverdueInfoService.queryByWhere(sql.toString());
		if(sdProjectOverdueInfoEntities.size()>0) {
			int flowindex = 0,milepostindex = 0,taskindex = 0;
			for(GpmProjectOverdueInfoEntity overdueInfoEntity : sdProjectOverdueInfoEntities) {
				if("1".equals(overdueInfoEntity.getOverduetype())) {
					flowindex++;
				} else if("2".equals(overdueInfoEntity.getOverduetype())) {
					milepostindex++;
				} else {
					taskindex++;
				}
			}
			content.appendSingle("项目执行过程中存在项目超期、", gpmProjectEntity.getTarget());
			if(flowindex>0) {
				content.appendSingle("{0}个流程超期",flowindex);
				if(milepostindex+taskindex > 0) {
					content.appendSingle("、",flowindex);
				} else {
					content.appendSingle("，",flowindex);
				}
			}
			if(milepostindex>0) {
				content.appendSingle("{0}个里程碑超期",milepostindex);
				if(taskindex > 0) {
					content.appendSingle("、",flowindex);
				} else {
					content.appendSingle("，",flowindex);
				}
			}
			if(taskindex>0) {
				content.appendSingle("{0}个任务超期,",taskindex);
			}
		}
		return content.toString();
	}
}
